Сам язык C++, C не имеет средств для поддержки многопоточной работы. Поэтому ответственность за многопоточную работу лежит на MFC раз мы ей пользуемся. Но MFC не использует взаимоисключений. Вот так. Вся ответственность за синхронизацию и доступ к объектам MFC лежит на нас. MFC проверяет доступ только для глобальных объектов и структур, но и то только в версии Debug. Но и это еще не все. В MFC нельзя пользоваться для создания потоков WIN 32 API. Вот так. Это связано с тем, что MFC при создании потоков проводит инициализацию всяких ей нужных переменных. Ну давайте посмотрим пример. Надо немного изменить предыдущий шаг.
UINT Threads(LPVOID pParam)
{
CWinApp* cw= AfxGetApp();
cw->HideApplication();
return 0;
}
void CTestThreadDlg::OnStart()
{
// TODO: Add your control notification handler code here
AfxBeginThread(Threads,NULL);
}
Мы из другого потока хотим получить доступ к объекту приложения, который создан в основном потоке приложения. Запустив приложение и нажав на кнопку в отладочной версии мы получим сообщение об ошибке.

При отладке мы увидим, что ошибка произошла вот здесь:
ASSERT((CWnd*)p == this);
А внизу примерно такое объяснение.
// Примечание: если любое из вышеупомянутого утверждений вызвано, и Вы // пишите multithreaded приложение, это вероятно // Вы передали C ++ объект от одной нити к другой // и использовали тот объект в процессе, который не был предназначен для этого. // (только простые встроенные функции должны использоваться) // ......
Вроде как что-то работает. Но обратите внимание на макрос ASSERT он работает только в отладочной версии и все. Переключитесь на конфигурацию Release используя меню Set Active Configuration и этот код сработает как миленький, как будто ничего и не бывало. Приложение спрячется. Найти его можно через Ctrl-Alt-Delete.
Вывод. MFC Вам не помощник и реализуйте синхронизацию сами !!!